package copyengine.network.roomStructure.executeLayer.impl.rtmfp
{
	import copyengine.network.roomStructure.executeLayer.CENetworkRoomModelConfig;
	import copyengine.network.roomStructure.executeLayer.IExecuteHandle;
	import copyengine.utils.GeneralUtils;
	import copyengine.utils.debug.CELog;

	import flash.events.NetStatusEvent;
	import flash.net.GroupSpecifier;
	import flash.net.NetConnection;
	import flash.net.NetGroup;
	import flash.utils.ByteArray;

	public final class RTMFPExecuteWarp
	{

		//当前的Warp是否可用(没有连接或者出现错误后均为不可用)
		private var isExecuteEnable:Boolean;

		private var netConnection:NetConnection;
		private var netGroup:NetGroup;

		private var groupName:String;

		private var executeHandle:IExecuteHandle;

		public function RTMFPExecuteWarp()
		{
		}

		public function initialize(_executeHandle:IExecuteHandle):void
		{
			executeHandle = _executeHandle;
			isExecuteEnable = false;
		}

		public function dispose():void
		{
			removeListener();
			disconnect();
			netGroup = null;
			netConnection = null;
		}

		/**
		 * 当前状态是否可用
		 */
		public function isEnable():Boolean
		{
			return isExecuteEnable;
		}

		public function connect(_rtmfpURL:String, _groupName:String):void
		{
			groupName = _groupName;
			netConnection = new NetConnection();
			netConnection.connect(_rtmfpURL);

			//需要分开AddListener
			GeneralUtils.addTargetEventListener(netConnection, NetStatusEvent.NET_STATUS, onNetConnectionStatus);
		}

		private function doConnectGroup():void
		{
			//配置连接到的Group消息
			var groupSpec:GroupSpecifier = new GroupSpecifier(groupName);
			groupSpec.serverChannelEnabled = true;
			groupSpec.ipMulticastMemberUpdatesEnabled = true;
			groupSpec.multicastEnabled = true;
			groupSpec.postingEnabled = true;

			//取得带授权的GroupID(授权的ID可以发送和接收消息)
			netGroup = new NetGroup(netConnection, groupSpec.groupspecWithAuthorizations());

			GeneralUtils.addTargetEventListener(netGroup, NetStatusEvent.NET_STATUS, onNetGroupStatus);

			CELog.log("RTMFPExecuteWarp->doConnectGroup start connect group : " + groupName);
		}

		public function disconnect():void
		{
			isExecuteEnable = false;
			netGroup.close();
			netConnection.close();
			executeHandle.onExecuteDisconnected(CENetworkRoomModelConfig.EXECUTE_WARP_TYPE_RTMFP);
		}

		/**
		 * @param _command 		发送给服务器端的命令
		 * @param _commandArg	命令带的参数(JSON格式)
		 * @param _forwardData		转发的数据包-加密后的ByteArray(服务器端不进行处理)
		 */
		public function sendData(_command:uint, _commandArg:Object, _forwardData:ByteArray = null):void
		{
			var msg:Object =
				{
					command:_command,
					commandArg:_commandArg,
					forwardData:_forwardData
				};
			netGroup.post(msg);
		}


		private function removeListener():void
		{
			GeneralUtils.removeTargetEventListener(netGroup, NetStatusEvent.NET_STATUS, onNetGroupStatus);
			GeneralUtils.removeTargetEventListener(netConnection, NetStatusEvent.NET_STATUS, onNetConnectionStatus);
		}

		private function onNetConnectionStatus(e:NetStatusEvent):void
		{
			if (e.info.code == "NetConnection.Connect.Success")
			{
				CELog.log("RTMFPExecuteWarp->onNetConnectionStatus netConnection connect succeed");
				//在连接服务器成功后开始连接Group
				doConnectGroup();
			}
			else if (e.info.code == "NetGroup.Connect.Success")
			{
				CELog.log("RTMFPExecuteWarp->onNetConnectionStatus group connect succeed");
				executeHandle.onExecuteConnected(CENetworkRoomModelConfig.EXECUTE_WARP_TYPE_RTMFP);
				isExecuteEnable = true;
			}
			else if (e.info.code == "NetGroup.Connect.Failed" ||
				e.info.code == "NetGroup.Connect.Rejected" ||
				e.info.code == "NetStream.Connect.Failed" ||
				e.info.code == "NetStream.Connect.Rejected")
			{
				CELog.err("RTMFPExecuteWarp->onNetConnectionStatus group connect failed");
				executeHandle.onExecuteError(CENetworkRoomModelConfig.EXECUTE_WARP_TYPE_RTMFP, e);
				disconnect();
			}
		}

		private function onNetGroupStatus(e:NetStatusEvent):void
		{
			if (e.info.code == "NetGroup.Posting.Notify")
			{
				var msg:Object = e.info.message;
				executeHandle.onReceiveExecuteData(CENetworkRoomModelConfig.EXECUTE_WARP_TYPE_RTMFP,
												   msg["command"],
												   msg["commandArg"],
												   msg["forwardData"]);
			}
		}

	}
}
